<!DOCTYPE HTML>
<html>

<head>
	<link rel="bookmark"  type="image/x-icon"  href="/img/logo_miccall.png"/>
	<link rel="shortcut icon" href="/img/logo_miccall.png">
	
			    <title>
    Ame雨
    </title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
    <link rel="stylesheet" href="/amelin-ting/css/mic_main.css" />
    <link rel="stylesheet" href="/amelin-ting/css/dropdownMenu.css" />
    <meta name="keywords" content="Ame雨" />
    
    	<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
	 
    <noscript>
        <link rel="stylesheet" href="/amelin-ting/css/noscript.css" />
    </noscript>
    <style type="text/css">
        body:before {
          content: ' ';
          position: fixed;
          top: 0;
          background: url('/amelin-ting/img/bg.jpg') center 0 no-repeat;
          right: 0;
          bottom: 0;
          left: 0;
          background-size: cover; 
        }
    </style>

			    
  
    <script type="text/x-mathjax-config">
      MathJax.Hub.Config({
        tex2jax: {
          inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
          processEscapes: true,
          skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
        }
      });
    </script>

    <script type="text/x-mathjax-config">
      MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for (i=0; i < all.length; i += 1) {
          all[i].SourceElement().parentNode.className += ' has-jax';
        }
      });
    </script>
    <script async type="text/javascript" src="//cdn.bootcss.com/mathjax/2.7.1/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
  


    <script src="/amelin-ting/js/jquery.min.js"></script>
    <script src="/amelin-ting/js/jquery.scrollex.min.js"></script>
    <script src="/amelin-ting/js/jquery.scrolly.min.js"></script>
    <script src="/amelin-ting/js/skel.min.js"></script>
    <script src="/amelin-ting/js/util.js"></script>
    <script src="/amelin-ting/js/main.js"></script>
	
<meta name="generator" content="Hexo 5.4.0"></head>
    
		
<!-- Layouts -->



<!--  代码渲染  -->
<link rel="stylesheet" href="/css/prism_coy.css" />
<link rel="stylesheet" href="/css/typo.css" />
<!-- 文章页 -->
<body class="is-loading">
    <!-- Wrapper 外包 s-->
    <div id="wrapper" class="fade-in">
        <!-- Intro 头部显示 s -->
        <!-- Intro 头部显示 e -->
        <!-- Header 头部logo start -->
        <header id="header">
    <a href="/amelin-ting/" class="logo">Art Space</a>
</header>
        <!-- Nav 导航条 start -->
        <nav id="nav" class="special" >
            <ul class="menu links" >
			<!-- Homepage  主页  --> 
			<li >
	            <a href="/amelin-ting/" rel="nofollow">主页</a>
	        </li>
			<!-- categories_name  分类   --> 
	        
	        <li class="active">
	            <a href="#s1">分类</a>
	                    <ul class="submenu">
	                        <li>
	                        <a class="category-link" href="/amelin-ting/categories/Go/">Go</a></li><li><a class="category-link" href="/amelin-ting/categories/django/">django</a></li><li><a class="category-link" href="/amelin-ting/categories/drf/">drf</a></li><li><a class="category-link" href="/amelin-ting/categories/gin/">gin</a></li><li><a class="category-link" href="/amelin-ting/categories/go/">go</a></li><li><a class="category-link" href="/amelin-ting/categories/linux/">linux</a></li><li><a class="category-link" href="/amelin-ting/categories/mysql/">mysql</a></li><li><a class="category-link" href="/amelin-ting/categories/python/">python</a></li><li><a class="category-link" href="/amelin-ting/categories/%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F/">内网穿透</a></li><li><a class="category-link" href="/amelin-ting/categories/%E5%89%8D%E7%AB%AF/">前端</a>
	                    </ul>
	        </li>
	        
	        <!-- archives  归档   --> 
	        
	        
		        <!-- Pages 自定义   -->
		        
		        <li>
		            <a href="/about/" title="简历">
		                简历
		            </a>
		        </li>
		        
		        <li>
		            <a href="/group/" title="团队">
		                团队
		            </a>
		        </li>
		        
		        <li>
		            <a href="/gallery/" title="图库">
		                图库
		            </a>
		        </li>
		        
		        <li>
		            <a href="/tag/" title="标签">
		                标签
		            </a>
		        </li>
		        


            </ul>
            <!-- icons 图标   -->
			<ul class="icons">
                    
                    <li>
                        <a title="github" href="https://github.com/miccall" target="_blank" rel="noopener">
                            <i class="icon fa fa-github"></i>
                        </a>
                    </li>
                    
                    <li>
                        <a title="500px" href="http://500px.com" target="_blank" rel="noopener">
                            <i class="icon fa fa-500px"></i>
                        </a>
                    </li>
                    
			</ul>
</nav>

        <div id="main" >
            <div class ="post_page_title_img" style="height: 25rem;background-image: url(https://img2.baidu.com/it/u=777661950,740942389&amp;fm=26&amp;fmt=auto);background-position: center; background-repeat:no-repeat; background-size:cover;-moz-background-size:cover;overflow:hidden;" >
                <a href="#" style="padding: 4rem 4rem 2rem 4rem ;"><h2 >python</h2></a>
            </div>
            <!-- Post -->
            <div class="typo" style="padding: 3rem;">
                <h1 id="并发编程"><a href="#并发编程" class="headerlink" title="并发编程"></a>并发编程</h1><h2 id="一、进程的调度"><a href="#一、进程的调度" class="headerlink" title="一、进程的调度"></a>一、进程的调度</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">程序就是文件里的一行行代码，他是个‘死的’</span></span><br><span class="line"><span class="string">进程则是文件代码运行起来，他是个‘活’的</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="comment"># 进程调度的方法</span></span><br><span class="line">	<span class="number">1.</span>先来先服务调度算法：对长程序有利 短程序无利</span><br><span class="line">    <span class="number">2.</span>短程序优先调度算法：对短程序有利 长程序无利</span><br><span class="line">    <span class="number">3.</span>时间片轮转算法与多级反馈队列</span><br></pre></td></tr></table></figure>

<h2 id="二、进程三状态图"><a href="#二、进程三状态图" class="headerlink" title="二、进程三状态图"></a>二、进程三状态图</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 程序在运行前 必须经历就绪阶段</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 前两行代码程序正在运行，在运行前得就绪 等待操作系统的运行</span></span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;程序正在运行&#x27;</span>)  <span class="comment"># 程序正在运行中</span></span><br><span class="line">name = <span class="built_in">input</span>(<span class="string">&#x27;--------------&gt;&#x27;</span>)  <span class="comment"># 堵塞状态，正在等待用户输入</span></span><br><span class="line"><span class="comment"># 输入好后 后面代码也不是立刻执行 ，也是在就绪状态，等待操作系统的运行</span></span><br><span class="line"><span class="built_in">print</span>(name)  <span class="comment"># 运行</span></span><br><span class="line">time.sleep(<span class="number">1</span>)  <span class="comment"># 堵塞</span></span><br><span class="line"><span class="comment"># 就绪</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;程序已经死亡&#x27;</span>)  <span class="comment"># 运行</span></span><br><span class="line"><span class="comment"># 死亡</span></span><br></pre></td></tr></table></figure>

<h2 id="三、同步异步与阻塞非阻塞"><a href="#三、同步异步与阻塞非阻塞" class="headerlink" title="三、同步异步与阻塞非阻塞"></a>三、同步异步与阻塞非阻塞</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;同步与异步&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="number">1.</span>同步  在程序执行完，在原地等着拿任务执行结果，不拿到就不走</span><br><span class="line"><span class="number">2.</span>异步  在提交了任务请求后，不在原地等着拿任务执行结果，直接执行下一个任务请求</span><br><span class="line">	<span class="comment">#  我们来想想异步那既然都走了怎么拿任务执行结果</span></span><br><span class="line">    	针对异步有一个异步回调的机制拿到结果</span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;阻塞与非阻塞&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="number">1.</span>阻塞     阻塞状态</span><br><span class="line"><span class="number">2.</span>非阻塞   运行状态</span><br><span class="line"></span><br><span class="line">理想状态：时时刻刻让程序保持运行状态</span><br><span class="line"></span><br><span class="line"><span class="comment"># 最有效率的的是搭配组合是  异步非阻塞</span></span><br></pre></td></tr></table></figure>

<h2 id="四、创建进程的两种方式"><a href="#四、创建进程的两种方式" class="headerlink" title="四、创建进程的两种方式"></a>四、创建进程的两种方式</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 两种方式其实我们都可以猜到啦，看我们学了 面对过程 还有 面对对象 那肯定就是这两种思路啦</span></span><br><span class="line"><span class="comment"># 面对过程</span></span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">func</span>(<span class="params">name</span>):</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;name&#125;</span>跑跑跑&#x27;</span>)</span><br><span class="line">    time.sleep(<span class="number">3</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;name&#125;</span>爬爬爬&#x27;</span>)</span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">	注意，windows我们想创建进程就得在main方法中，要不然会带来致命性的影响，那就是死循环，因为windows的创建进程就是类似于模块导入的，会自上而下的执行代码</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    g = Process(target=func, args=(<span class="string">&#x27;Ame&#x27;</span>,))  <span class="comment"># 注意元组里面只有一个元素的时候必须加逗号</span></span><br><span class="line">    g.start()  <span class="comment"># 异步</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;滚滚滚&#x27;</span>)  </span><br><span class="line"></span><br><span class="line">    </span><br><span class="line">  </span><br><span class="line"><span class="comment"># 面对对象</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyProcess</span>(<span class="params">Process</span>):</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">run</span>(<span class="params">self</span>):</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;hahah&#x27;</span>)</span><br><span class="line">        time.sleep(<span class="number">3</span>)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;gagag&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    g = MyProcess()</span><br><span class="line">    g.start()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;asd&#x27;</span>)</span><br></pre></td></tr></table></figure>

<h2 id="五、join方法"><a href="#五、join方法" class="headerlink" title="五、join方法"></a>五、join方法</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 我们在上面写了两种方式，一个是面对过程 一个是面对对象，我们平时用面对过程还是很多的，所以我们拿面对过程来举例</span></span><br><span class="line">    <span class="keyword">import</span> time</span><br><span class="line">    <span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">func</span>(<span class="params">name</span>):</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;name&#125;</span>跑跑跑&#x27;</span>)</span><br><span class="line">        time.sleep(<span class="number">3</span>)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;name&#125;</span>爬爬爬&#x27;</span>)</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">        g = Process(target=func, args=(<span class="string">&#x27;Ame&#x27;</span>,))  <span class="comment"># 注意元组里面只有一个元素的时候必须加逗号</span></span><br><span class="line">        g.start()  <span class="comment"># 异步</span></span><br><span class="line">        g.join()  <span class="comment"># 主进程必须等到子进程结束后才会实施</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;滚滚滚&#x27;</span>)  </span><br><span class="line"><span class="comment"># 我们想让‘滚滚滚’在爬爬爬这个子进程结束后才会显示出来，我们就得在后面加一个join方法，join()是主进程必须等到子进程结束后才会实施，我们在弄多个子进程来看看这个join更具体的用法</span></span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">func</span>(<span class="params">name, n</span>):</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;name&#125;</span>跑跑跑&#x27;</span>)</span><br><span class="line">    time.sleep(n)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;name&#125;</span>爬爬爬&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    g1 = Process(target=func, args=(<span class="string">&#x27;Yuki&#x27;</span>,<span class="number">1</span>))  <span class="comment"># 注意元组里面只有一个元素的时候必须加逗号</span></span><br><span class="line">    g2 = Process(target=func, args=(<span class="string">&#x27;Ame&#x27;</span>,<span class="number">2</span>))  <span class="comment"># 注意元组里面只有一个元素的时候必须加逗号</span></span><br><span class="line">    g3 = Process(target=func, args=(<span class="string">&#x27;Egon&#x27;</span>,<span class="number">3</span>))  <span class="comment"># 注意元组里面只有一个元素的时候必须加逗号</span></span><br><span class="line">    start_time = time.time()</span><br><span class="line">    g1.start()  <span class="comment"># 异步</span></span><br><span class="line">    g2.start()  <span class="comment"># 异步</span></span><br><span class="line">    g3.start()  <span class="comment"># 异步</span></span><br><span class="line">    g1.join()</span><br><span class="line">    g2.join()</span><br><span class="line">    g3.join()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;滚滚滚&#x27;</span>, time.time() - start_time)</span><br><span class="line"><span class="comment"># 我们会发现这个时间在子进程完全结束的时候，主进程也最后结束的时候还是只花了3秒钟，同时也要提示，别看g1,g2,g3,看似是有顺序的，实际上是没有顺序的</span></span><br><span class="line"><span class="comment"># 这个join其实是很少用到的，但是一定还是得要懂得其原理</span></span><br></pre></td></tr></table></figure>

<h2 id="六、进程间的数据相互隔离"><a href="#六、进程间的数据相互隔离" class="headerlink" title="六、进程间的数据相互隔离"></a>六、进程间的数据相互隔离</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 进程间的其实所有的数据都是隔离的，我们来证明这一点</span></span><br><span class="line">    <span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"></span><br><span class="line">    number = <span class="number">100</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">func</span>():</span></span><br><span class="line">        <span class="keyword">global</span> number</span><br><span class="line">        number = <span class="number">666</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">        b = Process(target=func)</span><br><span class="line">        b.start()</span><br><span class="line">        <span class="built_in">print</span>(number)  <span class="comment"># 100</span></span><br><span class="line">   </span><br><span class="line"><span class="comment"># 我们发现其实number还是100，并没有函数内改为666，这也是证明了进程间的所有数据都是隔离的，如果你们不信，可以在证明下</span></span><br><span class="line">    <span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"></span><br><span class="line">    number = <span class="number">100</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">func</span>():</span></span><br><span class="line">        <span class="keyword">global</span> number</span><br><span class="line">        number = <span class="number">666</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;as&#x27;</span>, number)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">        b = Process(target=func)</span><br><span class="line">        b.start()</span><br><span class="line">        b.join()</span><br><span class="line">        <span class="built_in">print</span>(number)</span><br><span class="line"><span class="comment"># 运行这个你们也就会发现，运行结果是as 666   100</span></span><br></pre></td></tr></table></figure>

<h2 id="七、进程对象及其他方法"><a href="#七、进程对象及其他方法" class="headerlink" title="七、进程对象及其他方法"></a>七、进程对象及其他方法</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;一台计算机运行了很多进程，那我们怎么才能知道这些进程，是因为计算机就直接把这些诸多进程都加上了PID&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">如何查看</span></span><br><span class="line"><span class="string">	windows 打开cmd，输入tasklist即可查看</span></span><br><span class="line"><span class="string">		tasklist|findstr PID查看具体进程</span></span><br><span class="line"><span class="string">	mac 打开终端 输入ps aux即可查看</span></span><br><span class="line"><span class="string">		ps aux|grep PID查看具体进程</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span>		</span><br><span class="line"><span class="keyword">from</span> multiprocessing <span class="keyword">import</span> current_process</span><br><span class="line">current_process().pid  <span class="comment"># 即可通过这个来查看当前进程的进程号</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line">os.getpid  <span class="comment"># 查看当前进程的进程号</span></span><br><span class="line">os.getppid  <span class="comment"># 查看当前进程的父进程号</span></span><br><span class="line"></span><br><span class="line">os.p.terminate()  <span class="comment"># 杀死这个进程</span></span><br><span class="line"><span class="built_in">print</span>(p.is_alive())  <span class="comment"># 判断当前这个进程是否存活</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">	其实要注意 假如这两行代码写一代码块，下面的为True，这是为什么，因为杀死这个进程是交给操作系统去杀死的，是需要少量时间的，然后执行的代码是很快的，所以得中间加个time.sleep(0.1)就好了，同时也要注意，凡是储存布尔值的变量名或者返回的是布尔值的方法名前缀都会是is</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>

<h2 id="八、僵尸进程与孤儿进程-了解"><a href="#八、僵尸进程与孤儿进程-了解" class="headerlink" title="八、僵尸进程与孤儿进程(了解)"></a>八、僵尸进程与孤儿进程(了解)</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;僵尸进程&quot;&quot;&quot;</span></span><br><span class="line">	僵尸进程就是死了没死透，依然还存在等着子进程去执行完，所有的进程都会变成僵尸进程，父进程运行完后还得观察子进程的各种信息，比如PID，子进程的运行时间，而且你运行了子程序后，子程序死后不会回收自己的PID，所以是父进程去帮忙回收</span><br><span class="line">    子进程结束后 父进程回去回收子进程的PID</span><br><span class="line">    或者就用join方法来回收子进程的PID</span><br><span class="line"><span class="string">&quot;&quot;&quot;孤儿进程&quot;&quot;&quot;</span></span><br><span class="line">    孤儿进程就是子进程存活，父进程意外死亡</span><br><span class="line">    这个时候操作系统会生成一个“儿童福利院”来回收这些子进程的PID</span><br></pre></td></tr></table></figure>

<h2 id="九、守护进程-了解"><a href="#九、守护进程-了解" class="headerlink" title="九、守护进程(了解)"></a>九、守护进程(了解)</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">func</span>(<span class="params">name</span>):</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;name&#125;</span>已经出生&#x27;</span>)</span><br><span class="line">    time.sleep(<span class="number">3</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;name&#125;</span>已经死亡&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    p = Process(target=func, args=<span class="string">&#x27;Alex&#x27;</span>)</span><br><span class="line">    p.daemon = <span class="literal">True</span>  <span class="comment"># 将进程P设成守护进程   这个必须加载start前面，否则会报错</span></span><br><span class="line">    p.start()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;Egon驾崩&#x27;</span>)</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="十、互斥锁"><a href="#十、互斥锁" class="headerlink" title="十、互斥锁"></a>十、互斥锁</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 大家有没有碰到这样的情况，就是在买票的时候明明还有票，可能过一会来看就没有票了，或者就是还剩下一张票的时候抢，发现没有票了，我们来模仿这个案例，来引出互斥锁</span></span><br><span class="line">    <span class="keyword">import</span> time</span><br><span class="line">    <span class="keyword">import</span> json</span><br><span class="line">    <span class="keyword">import</span> random</span><br><span class="line">    <span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Lock</span><br><span class="line">    <span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment"># 查看票数</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">check_ticker</span>(<span class="params">i</span>):</span></span><br><span class="line">        <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;ticket_data.json&#x27;</span>, mode=<span class="string">&#x27;rt&#x27;</span>, encoding=<span class="string">&#x27;utf8&#x27;</span>) <span class="keyword">as</span> file:</span><br><span class="line">            file = json.load(file)</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">f&quot;用户<span class="subst">&#123;i&#125;</span>查询票还剩下<span class="subst">&#123;file[<span class="string">&#x27;ticket&#x27;</span>]&#125;</span>&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment"># 购买票</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">buy_ticket</span>(<span class="params">i</span>):</span></span><br><span class="line">        <span class="comment"># 查票</span></span><br><span class="line">        <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;ticket_data.json&#x27;</span>, mode=<span class="string">&#x27;rt&#x27;</span>, encoding=<span class="string">&#x27;utf8&#x27;</span>) <span class="keyword">as</span> file:</span><br><span class="line">            file = json.load(file)</span><br><span class="line">            <span class="comment"># 模仿网络延迟</span></span><br><span class="line">        time.sleep(random.randint(<span class="number">1</span>, <span class="number">4</span>))</span><br><span class="line">        <span class="keyword">if</span> file.get(<span class="string">&#x27;ticket&#x27;</span>) &gt; <span class="number">0</span>:</span><br><span class="line">            file[<span class="string">&#x27;ticket&#x27;</span>] -= <span class="number">1</span></span><br><span class="line">            <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;ticket_data.json&#x27;</span>, mode=<span class="string">&#x27;wt&#x27;</span>, encoding=<span class="string">&#x27;utf8&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line">                json.dump(file, f)</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">f&quot;用户<span class="subst">&#123;i&#125;</span>购买成功&quot;</span>)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">f&#x27;用户<span class="subst">&#123;i&#125;</span>购买失败&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">run</span>(<span class="params">i, mutex</span>):</span></span><br><span class="line">        check_ticker(i)</span><br><span class="line">        <span class="comment"># 生锁</span></span><br><span class="line">        mutex.acquire()</span><br><span class="line">        buy_ticket(i)</span><br><span class="line">        <span class="comment"># 解锁</span></span><br><span class="line">        mutex.release()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">        <span class="comment"># 在主进程中生成一把锁 让所有的子进程抢 谁先抢到谁先买票</span></span><br><span class="line">        mutex = Lock()</span><br><span class="line">        <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>,<span class="number">11</span>):</span><br><span class="line">            p = Process(target=run, args=(i, mutex))</span><br><span class="line">            p.start()</span><br><span class="line">           </span><br><span class="line">       </span><br><span class="line">   </span><br><span class="line"><span class="comment"># 从这里可以看出锁就是从并行变成了串行，为了数据的安全性 只能牺牲了效率</span></span><br></pre></td></tr></table></figure>

<h2 id="十一、队列介绍"><a href="#十一、队列介绍" class="headerlink" title="十一、队列介绍"></a>十一、队列介绍</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Queue</span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建队列</span></span><br><span class="line">q = Queue(<span class="number">5</span>)  <span class="comment"># 设置队列的大小，只能存放5个队列</span></span><br><span class="line"></span><br><span class="line">q.put(<span class="number">111</span>)  <span class="comment"># put 就可以传入队列的值</span></span><br><span class="line">q.put(<span class="number">222</span>)  <span class="comment"># put 就可以传入队列的值</span></span><br><span class="line">q.put(<span class="number">333</span>)  <span class="comment"># put 就可以传入队列的值</span></span><br><span class="line">q.put(<span class="number">444</span>)  <span class="comment"># put 就可以传入队列的值</span></span><br><span class="line">q.put(<span class="number">555</span>)  <span class="comment"># put 就可以传入队列的值</span></span><br><span class="line"><span class="built_in">print</span>(q.empty())</span><br><span class="line"><span class="built_in">print</span>(q.full())</span><br><span class="line">v1 = q.get()</span><br><span class="line">v2 = q.get()</span><br><span class="line">v3 = q.get()</span><br><span class="line">v4 = q.get()</span><br><span class="line">v5 = q.get()</span><br><span class="line"><span class="built_in">print</span>(q.empty())</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">q.empty()  判断队列是否为空</span></span><br><span class="line"><span class="string">q.full()   判断队列是否为满</span></span><br><span class="line"><span class="string">q.get_nowait   收不到值不等待立刻报错</span></span><br><span class="line"><span class="string">q.</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>

<h2 id="十二、lpc-机制"><a href="#十二、lpc-机制" class="headerlink" title="十二、lpc 机制"></a>十二、lpc 机制</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;进程之间的通信&quot;&quot;&quot;</span></span><br><span class="line"><span class="comment"># 两种思路1.实现主进程与子进程之间的通信 2.实现子进程与子进程之间的通信</span></span><br><span class="line"><span class="number">1.</span></span><br><span class="line">	<span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Queue</span><br><span class="line">    <span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">communication</span>(<span class="params">p</span>):</span></span><br><span class="line">        p.put(<span class="string">&#x27;32技师为您服务&#x27;</span>)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;hello big baby~&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">        p = Queue()</span><br><span class="line">        q = Process(target=communication, args=(p,))</span><br><span class="line">        q.start()</span><br><span class="line">        <span class="built_in">print</span>(p.get())</span><br><span class="line">        </span><br><span class="line"><span class="number">2.</span></span><br><span class="line">    <span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Queue</span><br><span class="line">    <span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">communication</span>(<span class="params">p</span>):</span></span><br><span class="line">        p.put(<span class="string">&#x27;32技师为您服务&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">happy</span>(<span class="params">p</span>):</span></span><br><span class="line">        <span class="built_in">print</span>(p.get())</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">        p = Queue()</span><br><span class="line">        q = Process(target=communication, args=(p,))</span><br><span class="line">        q1 = Process(target=happy, args=(p,))</span><br><span class="line">        q.start()</span><br><span class="line">        q1.start()</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="十三、生产者与消费者模型"><a href="#十三、生产者与消费者模型" class="headerlink" title="十三、生产者与消费者模型"></a>十三、生产者与消费者模型</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 运用Queue  </span></span><br><span class="line">    <span class="keyword">import</span> time</span><br><span class="line">    <span class="keyword">import</span> random</span><br><span class="line">    <span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line">    <span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Queue</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">producer</span>(<span class="params">name, food, q</span>):</span></span><br><span class="line">        <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>):  <span class="comment"># 生产9次</span></span><br><span class="line">            data = <span class="string">f&#x27;<span class="subst">&#123;name&#125;</span>生产了<span class="subst">&#123;food&#125;</span><span class="subst">&#123;i&#125;</span>&#x27;</span></span><br><span class="line">            time.sleep(random.randint(<span class="number">1</span>, <span class="number">3</span>))</span><br><span class="line">            <span class="built_in">print</span>(data)</span><br><span class="line">            <span class="comment"># 放入队列中</span></span><br><span class="line">            q.put(data)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">consumer</span>(<span class="params">name, q</span>):</span></span><br><span class="line">        <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">            food = q.get()</span><br><span class="line">            <span class="keyword">if</span> food <span class="keyword">is</span> <span class="literal">None</span>: <span class="keyword">break</span></span><br><span class="line">            time.sleep(random.randint(<span class="number">1</span>, <span class="number">2</span>))</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;name&#125;</span>把<span class="subst">&#123;food&#125;</span>都吃了&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">        q = Queue()</span><br><span class="line">        bot1 = Process(target=producer, args=(<span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;泔水&#x27;</span>, q))</span><br><span class="line">        bot2 = Process(target=producer, args=(<span class="string">&#x27;2&#x27;</span>, <span class="string">&#x27;包子&#x27;</span>, q))</span><br><span class="line">        eater = Process(target=consumer, args=(<span class="string">&#x27;3&#x27;</span>, q))</span><br><span class="line">        bot1.start()</span><br><span class="line">        bot2.start()</span><br><span class="line">        eater.start()</span><br><span class="line">        bot1.join()</span><br><span class="line">        bot2.join()</span><br><span class="line">        q.put(<span class="literal">None</span>)</span><br><span class="line">        q.put(<span class="literal">None</span>)</span><br><span class="line"><span class="comment"># 运用 JionableQueue</span></span><br><span class="line">    <span class="keyword">import</span> time</span><br><span class="line">    <span class="keyword">import</span> random</span><br><span class="line">    <span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line">    <span class="keyword">from</span> multiprocessing <span class="keyword">import</span> JoinableQueue</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">producer</span>(<span class="params">name, food, q</span>):</span></span><br><span class="line">        <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>):  <span class="comment"># 生产9次</span></span><br><span class="line">            data = <span class="string">f&#x27;<span class="subst">&#123;name&#125;</span>生产了<span class="subst">&#123;food&#125;</span><span class="subst">&#123;i&#125;</span>&#x27;</span></span><br><span class="line">            time.sleep(random.randint(<span class="number">1</span>, <span class="number">3</span>))</span><br><span class="line">            <span class="built_in">print</span>(data)</span><br><span class="line">            <span class="comment"># 放入队列中</span></span><br><span class="line">            q.put(data)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">consumer</span>(<span class="params">name, q</span>):</span></span><br><span class="line">        <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">            food = q.get()</span><br><span class="line">            time.sleep(random.randint(<span class="number">1</span>, <span class="number">2</span>))</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;name&#125;</span>把<span class="subst">&#123;food&#125;</span>都吃了&#x27;</span>)</span><br><span class="line">            q.task_done()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">        q = JoinableQueue()</span><br><span class="line">        bot1 = Process(target=producer, args=(<span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;馒头&#x27;</span>, q))</span><br><span class="line">        bot2 = Process(target=producer, args=(<span class="string">&#x27;2&#x27;</span>, <span class="string">&#x27;包子&#x27;</span>, q))</span><br><span class="line">        eater = Process(target=consumer, args=(<span class="string">&#x27;3&#x27;</span>, q))</span><br><span class="line">        bot1.start()</span><br><span class="line">        bot2.start()</span><br><span class="line">        eater.daemon = <span class="literal">True</span></span><br><span class="line">        eater.start()</span><br><span class="line">        bot1.join()</span><br><span class="line">        bot2.join()</span><br><span class="line">        q.join() </span><br></pre></td></tr></table></figure>

<h2 id="十四、线程理论"><a href="#十四、线程理论" class="headerlink" title="十四、线程理论"></a>十四、线程理论</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">1. 什么是线程</span></span><br><span class="line"><span class="string">	如果把操作系统比作成一个大工厂，进程就是里面一个个的车间，线程就是车间里的一个个流水线</span></span><br><span class="line"><span class="string">	每一个进程肯定自带一个线程</span></span><br><span class="line"><span class="string">	进程里面可以有多个线程</span></span><br><span class="line"><span class="string">	线程和进程都是虚拟概念，只是为了方便我们去理解他</span></span><br><span class="line"><span class="string">	再次总结</span></span><br><span class="line"><span class="string">		进程就是开辟了一块块内存空间</span></span><br><span class="line"><span class="string">		线程则是真的CPU运行的那一段段代码</span></span><br><span class="line"><span class="string">2. 为什么用线程</span></span><br><span class="line"><span class="string">	每建立一个进程 就会多开辟一个内存空间，但是一个进程里面可以有多个线程，所以用线程会大大减少内存的使用</span></span><br><span class="line"><span class="string">	比如我们要开发一个文本编辑器，需求如下</span></span><br><span class="line"><span class="string">		获取用户输入的功能</span></span><br><span class="line"><span class="string">		时刻能追加文字显示到屏幕</span></span><br><span class="line"><span class="string">		能自动保存</span></span><br><span class="line"><span class="string">			这很明显就是要搞多个线程，因为一个进程里面的多个线程数据是共享的</span></span><br><span class="line"><span class="string">3. 怎么用线程</span></span><br><span class="line"><span class="string">	后面再讲~~~~~~~~~~~~~~~~~·</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>

<h2 id="十五、开启线程的两种方式"><a href="#十五、开启线程的两种方式" class="headerlink" title="十五、开启线程的两种方式"></a>十五、开启线程的两种方式</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 面对过程</span></span><br><span class="line">    <span class="keyword">from</span> threading <span class="keyword">import</span> Thread</span><br><span class="line">    <span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">func</span>(<span class="params">name</span>):</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;%s is running&#x27;</span> % name)</span><br><span class="line">        time.sleep(<span class="number">1</span>)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;name&#125;</span> is over&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">        q = Thread(target=func, args=(<span class="string">&#x27;Egon&#x27;</span>,))</span><br><span class="line">        q.start()</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;主&#x27;</span>)</span><br><span class="line"> </span><br><span class="line"><span class="comment"># 面对对象</span></span><br><span class="line">    <span class="keyword">from</span> threading <span class="keyword">import</span> Thread</span><br><span class="line">    <span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="class"><span class="keyword">class</span> <span class="title">MyThread</span>(<span class="params">Thread</span>):</span></span><br><span class="line">        <span class="function"><span class="keyword">def</span> <span class="title">__init__</span>(<span class="params">self, name</span>):</span></span><br><span class="line">            <span class="built_in">super</span>().__init__()</span><br><span class="line">            self.name = name</span><br><span class="line"></span><br><span class="line">        <span class="function"><span class="keyword">def</span> <span class="title">run</span>(<span class="params">self</span>):</span></span><br><span class="line">            <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.name&#125;</span> is running&#x27;</span>)</span><br><span class="line">            time.sleep(<span class="number">1</span>)</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.name&#125;</span> is over&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">        q = MyThread(<span class="string">&#x27;Egon&#x27;</span>)</span><br><span class="line">        q.start()</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;主&#x27;</span>)</span><br><span class="line"> </span><br><span class="line"><span class="comment"># 注意 因为开启线程不需要在开启一块独立的内存空间，而开启进程则需要，所以你会发现“主”在线程之后才显示出来，比进程快多了</span></span><br></pre></td></tr></table></figure>

<h2 id="十六、TCP服务端实现并发的效果"><a href="#十六、TCP服务端实现并发的效果" class="headerlink" title="十六、TCP服务端实现并发的效果"></a>十六、TCP服务端实现并发的效果</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 服务端</span></span><br><span class="line">	<span class="keyword">import</span> socket</span><br><span class="line">    <span class="keyword">from</span> threading <span class="keyword">import</span> Thread</span><br><span class="line"></span><br><span class="line">    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)</span><br><span class="line">    server.bind((<span class="string">&quot;127.0.0.1&quot;</span>, <span class="number">6666</span>))</span><br><span class="line">    server.listen(<span class="number">5</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">task</span>(<span class="params">conn</span>):</span></span><br><span class="line">        <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">            <span class="keyword">try</span>:</span><br><span class="line">                data = conn.recv(<span class="number">1024</span>)</span><br><span class="line">                <span class="keyword">if</span> <span class="built_in">len</span>(data) == <span class="number">0</span>: <span class="keyword">break</span></span><br><span class="line">                <span class="built_in">print</span>(data.decode(<span class="string">&#x27;utf8&#x27;</span>))</span><br><span class="line">                conn.send(data.upper())</span><br><span class="line"></span><br><span class="line">            <span class="keyword">except</span> EnvironmentError:</span><br><span class="line">                <span class="keyword">break</span></span><br><span class="line">            conn.close()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">        conn, addr = server.accept()</span><br><span class="line">        q = Thread(target=task, args=(conn,))</span><br><span class="line">        q.start()</span><br><span class="line">        </span><br><span class="line">        </span><br><span class="line"><span class="comment"># 客户端</span></span><br><span class="line">    <span class="keyword">import</span> socket</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    client = socket.socket()</span><br><span class="line">    client.connect((<span class="string">&#x27;127.0.0.1&#x27;</span>, <span class="number">6666</span>))</span><br><span class="line">    <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">        client.send(<span class="string">&#x27;hello world&#x27;</span>.encode(<span class="string">&#x27;utf8&#x27;</span>))</span><br><span class="line">        data = client.recv(<span class="number">1024</span>)</span><br><span class="line">        <span class="built_in">print</span>(data.decode(<span class="string">&#x27;utf-8&#x27;</span>))</span><br></pre></td></tr></table></figure>

<h2 id="十七、线程的join方法"><a href="#十七、线程的join方法" class="headerlink" title="十七、线程的join方法"></a>十七、线程的join方法</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;JION方法&quot;&quot;&quot;</span></span><br><span class="line"><span class="keyword">from</span> threading <span class="keyword">import</span> Thread</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">func</span>(<span class="params">name</span>):</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;%s is running&#x27;</span> % name)</span><br><span class="line">    time.sleep(<span class="number">1</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;name&#125;</span> is over&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    q = Thread(target=func, args=(<span class="string">&#x27;Egon&#x27;</span>,))</span><br><span class="line">    q.start()</span><br><span class="line">    q.join()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;主&#x27;</span>)</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="十八、同一个进程下的多个线程"><a href="#十八、同一个进程下的多个线程" class="headerlink" title="十八、同一个进程下的多个线程"></a>十八、同一个进程下的多个线程</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;线程之间数据是通用的&quot;&quot;&quot;</span></span><br><span class="line"><span class="keyword">from</span> threading <span class="keyword">import</span> Thread</span><br><span class="line"></span><br><span class="line">money = <span class="number">100</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">balance</span>():</span></span><br><span class="line">    <span class="keyword">global</span> money</span><br><span class="line">    money = <span class="number">222</span></span><br><span class="line">    <span class="built_in">print</span>(money)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">q = Thread(target=balance())</span><br><span class="line">q.start()</span><br><span class="line"><span class="built_in">print</span>(money)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 跟进程不一样，线程之间数据是通用的</span></span><br></pre></td></tr></table></figure>

<h2 id="十九、线程对象及其他办法"><a href="#十九、线程对象及其他办法" class="headerlink" title="十九、线程对象及其他办法"></a>十九、线程对象及其他办法</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> threading <span class="keyword">import</span> Thread, active_count, current_thread</span><br><span class="line"><span class="keyword">import</span> os,time</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">task</span>(<span class="params">n</span>):</span></span><br><span class="line">    <span class="comment"># print(&#x27;hello world&#x27;,os.getpid())</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;hello world&#x27;</span>,current_thread().name)</span><br><span class="line">    time.sleep(n)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    t = Thread(target=task,args=(<span class="number">1</span>,))</span><br><span class="line">    t1 = Thread(target=task,args=(<span class="number">2</span>,))</span><br><span class="line">    t.start()</span><br><span class="line">    t1.start()</span><br><span class="line">    t.join()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;主&#x27;</span>,active_count())  <span class="comment"># 统计当前正在活跃的线程数</span></span><br><span class="line">    <span class="comment"># print(&#x27;主&#x27;,os.getpid())</span></span><br><span class="line">    <span class="comment"># print(&#x27;主&#x27;,current_thread().name)  # 获取线程名字</span></span><br></pre></td></tr></table></figure>

<h2 id="二十、守护线程"><a href="#二十、守护线程" class="headerlink" title="二十、守护线程"></a>二十、守护线程</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;守护线程&quot;&quot;&quot;</span></span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">from</span> threading <span class="keyword">import</span> Thread</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">func</span>():</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="number">123</span>)</span><br><span class="line">    time.sleep(<span class="number">1</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;dd123&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    q = Thread(target=func)</span><br><span class="line">    q.daemon = <span class="literal">True</span></span><br><span class="line">    q.start()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;主&#x27;</span>)</span><br><span class="line">    </span><br><span class="line"><span class="string">&quot;&quot;&quot;具有迷惑性的守护线程例子&quot;&quot;&quot;</span></span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">from</span> threading <span class="keyword">import</span> Thread</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">func</span>():</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="number">123</span>)</span><br><span class="line">    time.sleep(<span class="number">1</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;end123&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">res</span>():</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="number">456</span>)</span><br><span class="line">    time.sleep(<span class="number">3</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;end456&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    q = Thread(target=func)</span><br><span class="line">    q1 = Thread(target=res)</span><br><span class="line">    q.daemon = <span class="literal">True</span></span><br><span class="line">    q.start()</span><br><span class="line">    q1.start()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;主&#x27;</span>)</span><br><span class="line">    </span><br><span class="line"><span class="comment"># 主进程执行完毕也不会死的，必须在没有守护的进程结束后，才会死，所以res是3s，func是1s，所以先后执行的顺序为123,456，主，end123，end456</span></span><br></pre></td></tr></table></figure>

<h2 id="二十一、线程互斥锁"><a href="#二十一、线程互斥锁" class="headerlink" title="二十一、线程互斥锁"></a>二十一、线程互斥锁</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;线程互斥锁&quot;&quot;&quot;</span></span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">from</span> threading <span class="keyword">import</span> Thread</span><br><span class="line"><span class="keyword">from</span> threading <span class="keyword">import</span> Lock</span><br><span class="line"></span><br><span class="line">money = <span class="number">100</span></span><br><span class="line">mutex = Lock()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">func</span>():</span></span><br><span class="line">    <span class="keyword">global</span> money</span><br><span class="line">    mutex.acquire()</span><br><span class="line">    tmp = money</span><br><span class="line">    time.sleep(<span class="number">0.1</span>)</span><br><span class="line">    money = tmp - <span class="number">1</span></span><br><span class="line">    mutex.release()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    q_list = []</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">100</span>):</span><br><span class="line">        q = Thread(target=func)</span><br><span class="line">        q.start()</span><br><span class="line">        q_list.append(q)</span><br><span class="line">    <span class="keyword">for</span> q <span class="keyword">in</span> q_list:</span><br><span class="line">        q.join()</span><br><span class="line">    <span class="built_in">print</span>(money)</span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="二十二、GIL全局解释器锁理论介绍-了解"><a href="#二十二、GIL全局解释器锁理论介绍-了解" class="headerlink" title="二十二、GIL全局解释器锁理论介绍(了解)"></a>二十二、GIL全局解释器锁理论介绍(了解)</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple </span></span><br><span class="line"><span class="string">native threads from executing Python bytecodes at once. This lock is necessary mainly </span></span><br><span class="line"><span class="string">because CPython’s memory management is not thread-safe. (However, since the GIL </span></span><br><span class="line"><span class="string">exists, other features have grown to depend on the guarantees that it enforces.)</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">python解释器其实有多个版本</span></span><br><span class="line"><span class="string">	Cpython</span></span><br><span class="line"><span class="string">	Jpython</span></span><br><span class="line"><span class="string">	Pypypython</span></span><br><span class="line"><span class="string">但是普遍使用的都是CPython解释器</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">在CPython解释器中GIL是一把互斥锁，用来阻止同一个进程下的多个线程的同时执行</span></span><br><span class="line"><span class="string">	同一个进程下的多个线程无法利用多核优势！！！</span></span><br><span class="line"><span class="string">	疑问:python的多线程是不是一点用都没有？？？无法利用多核优势</span></span><br><span class="line"><span class="string">	</span></span><br><span class="line"><span class="string">因为cpython中的内存管理不是线程安全的</span></span><br><span class="line"><span class="string">内存管理(垃圾回收机制)</span></span><br><span class="line"><span class="string">	1.应用计数</span></span><br><span class="line"><span class="string">	2.标记清楚</span></span><br><span class="line"><span class="string">	3.分代回收</span></span><br><span class="line"><span class="string">	</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">重点:</span></span><br><span class="line"><span class="string">	1.GIL不是python的特点而是CPython解释器的特点</span></span><br><span class="line"><span class="string">	2.GIL是保证解释器级别的数据的安全</span></span><br><span class="line"><span class="string">	3.GIL会导致同一个进程下的多个线程的无法同时执行即无法利用多核优势(******)</span></span><br><span class="line"><span class="string">	4.针对不同的数据还是需要加不同的锁处理 </span></span><br><span class="line"><span class="string">	5.解释型语言的通病:同一个进程下多个线程无法利用多核优势</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>

<h2 id="二十三、GIL与普通互斥锁的区别"><a href="#二十三、GIL与普通互斥锁的区别" class="headerlink" title="二十三、GIL与普通互斥锁的区别"></a>二十三、GIL与普通互斥锁的区别</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> threading <span class="keyword">import</span> Thread,Lock</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">mutex = Lock()</span><br><span class="line">money = <span class="number">100</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">task</span>():</span></span><br><span class="line">    <span class="keyword">global</span> money</span><br><span class="line">    <span class="comment"># with mutex:</span></span><br><span class="line">    <span class="comment">#     tmp = money</span></span><br><span class="line">    <span class="comment">#     time.sleep(0.1)</span></span><br><span class="line">    <span class="comment">#     money = tmp -1</span></span><br><span class="line">    mutex.acquire()</span><br><span class="line">    tmp = money</span><br><span class="line">    time.sleep(<span class="number">0.1</span>)  <span class="comment"># 只要你进入IO了 GIL会自动释放</span></span><br><span class="line">    money = tmp - <span class="number">1</span></span><br><span class="line">    mutex.release()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    t_list = []</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">100</span>):</span><br><span class="line">        t = Thread(target=task)</span><br><span class="line">        t.start()</span><br><span class="line">        t_list.append(t)</span><br><span class="line">    <span class="keyword">for</span> t <span class="keyword">in</span> t_list:</span><br><span class="line">        t.join()</span><br><span class="line">    <span class="built_in">print</span>(money)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">100个线程起起来之后  要先去抢GIL</span></span><br><span class="line"><span class="string">我进入io GIL自动释放 但是我手上还有一个自己的互斥锁</span></span><br><span class="line"><span class="string">其他线程虽然抢到了GIL但是抢不到互斥锁 </span></span><br><span class="line"><span class="string">最终GIL还是回到你的手上 你去操作数据</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>

<h2 id="二十四、同一个进程下的多线程无法利用多核优势-是不是就没有用了"><a href="#二十四、同一个进程下的多线程无法利用多核优势-是不是就没有用了" class="headerlink" title="二十四、同一个进程下的多线程无法利用多核优势,是不是就没有用了"></a>二十四、同一个进程下的多线程无法利用多核优势,是不是就没有用了</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">多线程是否有用要看具体情况</span></span><br><span class="line"><span class="string">单核:四个任务(IO密集型\计算密集型)</span></span><br><span class="line"><span class="string">多核:四个任务(IO密集型\计算密集型)</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="comment"># 计算密集型   每个任务都需要10s</span></span><br><span class="line">单核(不用考虑了)</span><br><span class="line">	多进程:额外的消耗资源</span><br><span class="line">  多线程:介绍开销</span><br><span class="line">多核</span><br><span class="line">	多进程:总耗时 <span class="number">10</span>+</span><br><span class="line">  多线程:总耗时 <span class="number">40</span>+</span><br><span class="line"><span class="comment"># IO密集型  </span></span><br><span class="line">多核</span><br><span class="line">	多进程:相对浪费资源</span><br><span class="line">  多线程:更加节省资源</span><br></pre></td></tr></table></figure>

<h3 id="24-1代码验证"><a href="#24-1代码验证" class="headerlink" title="24.1代码验证"></a>24.1代码验证</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 计算密集型</span></span><br><span class="line"><span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"><span class="keyword">from</span> threading <span class="keyword">import</span> Thread</span><br><span class="line"><span class="keyword">import</span> os, time</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">work</span>():</span></span><br><span class="line">    res = <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10000000</span>):</span><br><span class="line">        res *= i</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    l = []</span><br><span class="line">    <span class="built_in">print</span>(os.cpu_count())  <span class="comment"># 获取当前计算机CPU个数</span></span><br><span class="line">    start_time = time.time()</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">12</span>):</span><br><span class="line">        p = Process(target=work)  <span class="comment"># 1.4679949283599854</span></span><br><span class="line">        t = Thread(target=work)  <span class="comment"># 5.698534250259399</span></span><br><span class="line">        t.start()</span><br><span class="line">        <span class="comment"># p.start()</span></span><br><span class="line">        <span class="comment"># l.append(p)</span></span><br><span class="line">        l.append(t)</span><br><span class="line">    <span class="keyword">for</span> p <span class="keyword">in</span> l:</span><br><span class="line">        p.join()</span><br><span class="line">    <span class="built_in">print</span>(time.time() - start_time)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># IO密集型</span></span><br><span class="line"><span class="keyword">from</span> multiprocessing <span class="keyword">import</span> Process</span><br><span class="line"><span class="keyword">from</span> threading <span class="keyword">import</span> Thread</span><br><span class="line"><span class="keyword">import</span> os,time</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">work</span>():</span></span><br><span class="line">    time.sleep(<span class="number">2</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    l = []</span><br><span class="line">    <span class="built_in">print</span>(os.cpu_count())  <span class="comment"># 获取当前计算机CPU个数</span></span><br><span class="line">    start_time = time.time()</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4000</span>):</span><br><span class="line">        <span class="comment"># p = Process(target=work)  # 21.149890184402466</span></span><br><span class="line">        t = Thread(target=work)  <span class="comment"># 3.007986068725586</span></span><br><span class="line">        t.start()</span><br><span class="line">        <span class="comment"># p.start()</span></span><br><span class="line">        <span class="comment"># l.append(p)</span></span><br><span class="line">        l.append(t)</span><br><span class="line">    <span class="keyword">for</span> p <span class="keyword">in</span> l:</span><br><span class="line">        p.join()</span><br><span class="line">    <span class="built_in">print</span>(time.time()-start_time)</span><br></pre></td></tr></table></figure>

<h3 id="24-2总结"><a href="#24-2总结" class="headerlink" title="24.2总结"></a>24.2总结</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">多进程和多线程都有各自的优势</span></span><br><span class="line"><span class="string">并且我们后面在写项目的时候通常可以</span></span><br><span class="line"><span class="string">	多进程下面再开设多线程</span></span><br><span class="line"><span class="string">这样的话既可以利用多核也可以介绍资源消耗</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>

<h2 id="二十五、死锁现象"><a href="#二十五、死锁现象" class="headerlink" title="二十五、死锁现象"></a>二十五、死锁现象</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> threading <span class="keyword">import</span> Thread</span><br><span class="line"><span class="keyword">from</span> threading <span class="keyword">import</span> Lock</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line">musex1 = Lock()</span><br><span class="line">musex2 = Lock()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyThread</span>(<span class="params">Thread</span>):</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">run</span>(<span class="params">self</span>):</span></span><br><span class="line">        self.run1()</span><br><span class="line">        self.run2()</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">run1</span>(<span class="params">self</span>):</span></span><br><span class="line">        musex1.acquire()</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.name&#125;</span>抢到了1锁&#x27;</span>)</span><br><span class="line">        musex2.acquire()</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.name&#125;</span>抢到了2锁&#x27;</span>)</span><br><span class="line">        musex2.release()</span><br><span class="line">        musex1.release()</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">run2</span>(<span class="params">self</span>):</span></span><br><span class="line">        musex2.acquire()</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.name&#125;</span>抢到了2锁&#x27;</span>)</span><br><span class="line">        time.sleep(<span class="number">3</span>)</span><br><span class="line">        musex1.acquire()</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.name&#125;</span>抢到了1锁&#x27;</span>)</span><br><span class="line">        musex1.release()</span><br><span class="line">        musex2.release()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>):</span><br><span class="line">        q = MyThread()</span><br><span class="line">        q.start()</span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">	这就是死锁，你运行了就会发现程序一直在卡死(阻塞)，我们来看原因，一开始第一个线程去抢1锁，抢到以后其他线程就只能看着，然后一线程抢2锁的时候肯定无忧无虑，因为其他线程还在外面待着，然后1线程解了2锁和1锁，这个时候有一个线程一进抢了1锁，1线程又去run2抢了2锁，这时候就尴尬了，2线程要2锁，1线程要1锁，就这成了死锁</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>

<h2 id="二十六、递归锁"><a href="#二十六、递归锁" class="headerlink" title="二十六、递归锁"></a>二十六、递归锁</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">递归锁的特点	</span></span><br><span class="line"><span class="string">	可以被连续的acquire和release</span></span><br><span class="line"><span class="string">	但是只能被第一个抢到这把锁执行上述操作</span></span><br><span class="line"><span class="string">	它的内部有一个计数器 每acquire一次计数加一 每realse一次计数减一</span></span><br><span class="line"><span class="string">	只要计数不为0 那么其他人都无法抢到该锁</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="comment"># 将上述的</span></span><br><span class="line">mutexA = Lock()</span><br><span class="line">mutexB = Lock()</span><br><span class="line"><span class="comment"># 换成</span></span><br><span class="line">mutexA = mutexB = RLock()</span><br></pre></td></tr></table></figure>

<h2 id="二十七、信号量"><a href="#二十七、信号量" class="headerlink" title="二十七、信号量"></a>二十七、信号量</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;注意 信号量在每个阶段所代表的都不一样，在这里表示的是互斥锁&quot;&quot;&quot;</span></span><br><span class="line"><span class="comment"># 如果把互斥锁比喻成厕所，那么信号量就是公共厕所(多个厕所)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 代码演练</span></span><br><span class="line"><span class="keyword">from</span> threading <span class="keyword">import</span> Thread</span><br><span class="line"><span class="keyword">from</span> threading <span class="keyword">import</span> Semaphore</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"></span><br><span class="line">sm = Semaphore(<span class="number">5</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">task</span>(<span class="params">name</span>):</span></span><br><span class="line">    sm.acquire()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;name&#125;</span>正在蹲坑&quot;</span>)</span><br><span class="line">    time.sleep(random.randint(<span class="number">1</span>, <span class="number">3</span>))</span><br><span class="line">    sm.release()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">20</span>):</span><br><span class="line">        q = Thread(target=task, args=(<span class="string">f&#x27;伞兵<span class="subst">&#123;i&#125;</span>号&#x27;</span>, ))</span><br><span class="line">        q.start()</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="二十八、Event事件"><a href="#二十八、Event事件" class="headerlink" title="二十八、Event事件"></a>二十八、Event事件</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;Event事件 是指一些线程和一些进程都会在其他的线程进程结束后才会执行，类似于发射信号&#x27;&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> threading <span class="keyword">import</span> Thread</span><br><span class="line"><span class="keyword">from</span> threading <span class="keyword">import</span> Event</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line">e = Event()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">light</span>():</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;红灯停&#x27;</span>)</span><br><span class="line">    time.sleep(<span class="number">3</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;绿灯行&#x27;</span>)</span><br><span class="line">    e.<span class="built_in">set</span>()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">car</span>(<span class="params">name</span>):</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;name&#125;</span>红灯停&#x27;</span>)</span><br><span class="line">    e.wait()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;name&#125;</span>绿灯行&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    q = Thread(target=light)</span><br><span class="line">    q.start()</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>):</span><br><span class="line">        q1 = Thread(target=car, args=(<span class="string">f&#x27;<span class="subst">&#123;i&#125;</span>&#x27;</span>, ))</span><br><span class="line">        q1.start()</span><br></pre></td></tr></table></figure>

<h2 id="二十九、线程q"><a href="#二十九、线程q" class="headerlink" title="二十九、线程q"></a>二十九、线程q</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">同一个进程下可以开启多个线程，并且数据是共享的</span></span><br><span class="line"><span class="string">那我们干嘛还非要进程下使用队列呢</span></span><br><span class="line"><span class="string">因为队列 是  管道+锁</span></span><br><span class="line"><span class="string">所以用队列还是为了数据安全</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="keyword">import</span> queue</span><br><span class="line"></span><br><span class="line"><span class="comment"># 我们现在的队列都是本地测试使用</span></span><br><span class="line"><span class="comment"># 队列q 先进先出</span></span><br><span class="line">q = queue.Queue(<span class="number">3</span>)</span><br><span class="line">q.put(<span class="number">1</span>)  <span class="comment"># 输入数据</span></span><br><span class="line">q.get()  <span class="comment"># 拿到数据</span></span><br><span class="line">q.get_nowait()</span><br><span class="line">q.empty()</span><br><span class="line">q.full()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 后进先出</span></span><br><span class="line">q = queue.LifoQueue()</span><br><span class="line">q.put(<span class="number">1</span>)</span><br><span class="line">q.put(<span class="number">2</span>)</span><br><span class="line">q.put(<span class="number">3</span>)</span><br><span class="line"><span class="built_in">print</span>(q.get())</span><br><span class="line"></span><br><span class="line"><span class="comment"># 优先级别q  你可以给队列中的q设置优先级</span></span><br><span class="line">q = queue.PriorityQueue(<span class="number">3</span>)</span><br><span class="line">q.put((<span class="number">10</span>, <span class="string">&#x27;asd&#x27;</span>))</span><br><span class="line">q.put((<span class="number">1</span>, <span class="string">&#x27;qwe&#x27;</span>))</span><br><span class="line">q.put((-<span class="number">5</span>, <span class="string">&#x27;zxc&#x27;</span>))</span><br><span class="line"><span class="built_in">print</span>(q.get())</span><br><span class="line"><span class="comment"># 数字越小 优先级越高</span></span><br></pre></td></tr></table></figure>

<h2 id="三十、池的概念介绍"><a href="#三十、池的概念介绍" class="headerlink" title="三十、池的概念介绍"></a>三十、池的概念介绍</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">	回想一下我们之前的tcp通信下的并发，每来一个客户端我们就创建一个进程</span></span><br><span class="line"><span class="string">	但是无论是开设进程也好线程也好，都会消耗资源，开多个线程消耗资源少，但是终归也是消耗了资源，我们的计算机硬件能让我们开无限多的进程或者线程嘛，当然不能，硬件的开发速度远比不上软件的开发速度，所以我们有个原则就是保证计算机硬件安全前，去最大化的利用资源</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;池的概念&quot;&quot;&quot;</span></span><br><span class="line"><span class="comment"># 池是在保证计算机硬件安全的时候，最大化利用起计算机资源的概念，他降低了程序运行效率，但是提高了计算机硬件的安全性，从而保证你的软件运行正常</span></span><br></pre></td></tr></table></figure>

<h2 id="三十一、线程池"><a href="#三十一、线程池" class="headerlink" title="三十一、线程池"></a>三十一、线程池</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> concurrent.futures <span class="keyword">import</span> ThreadPoolExecutor</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line">pool = ThreadPoolExecutor(<span class="number">5</span>)  <span class="comment"># 括号内的参数可以不传 默认是开启计算机cpu个数的5倍的线程 写了5池子里就是开启5个线程</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">池子造出来后，里面会固定存在5个线程，这个五个线程不会重复创建和销毁</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">task</span>(<span class="params">n</span>):</span></span><br><span class="line">    <span class="built_in">print</span>(n)</span><br><span class="line">    time.sleep(<span class="number">2</span>)</span><br><span class="line">    <span class="keyword">return</span> n ** n</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">l_list = []</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">20</span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">    讲到提交任务就会想到同步异步两种方法</span></span><br><span class="line"><span class="string">    同步：提交完任务在原地等数据结果的到来，不会离开</span></span><br><span class="line"><span class="string">    异步：提交完任务便执行下一步代码，不会原地等待数据结果的到来</span></span><br><span class="line"><span class="string">    &quot;&quot;&quot;</span></span><br><span class="line">    res = pool.submit(task, i)  <span class="comment"># 向池子提交任务即可</span></span><br><span class="line">    l_list.append(res)</span><br><span class="line"></span><br><span class="line">pool.shutdown()  <span class="comment"># 关闭线程池 等待线程池里面的线程所有的任务运行完毕</span></span><br><span class="line"><span class="keyword">for</span> t <span class="keyword">in</span> l_list:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;----&gt;&#x27;</span>, t.result())</span><br><span class="line">    <span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">    result 会让程序并发变成串行，并且返回异步提交任务的返回结果</span></span><br><span class="line"><span class="string">    &quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>

<h2 id="三十二、进程池"><a href="#三十二、进程池" class="headerlink" title="三十二、进程池"></a>三十二、进程池</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> concurrent.futures <span class="keyword">import</span> ProcessPoolExecutor</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line">pool = ProcessPoolExecutor(<span class="number">5</span>)  <span class="comment"># 括号内的参数可以不传 默认是开启计算机cpu个数的5倍的线程 写了5池子里就是开启5个线程</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">池子造出来后，里面会固定存在5个线程，这个五个线程不会重复创建和销毁</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">task</span>(<span class="params">n</span>):</span></span><br><span class="line">    <span class="built_in">print</span>(n)</span><br><span class="line">    time.sleep(<span class="number">2</span>)</span><br><span class="line">    <span class="keyword">return</span> n ** n</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">callback</span>(<span class="params">n</span>):</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;-----&gt;&#x27;</span>, n.result())</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">20</span>):</span><br><span class="line">        <span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">        讲到提交任务就会想到同步异步两种方法</span></span><br><span class="line"><span class="string">        同步：提交完任务在原地等数据结果的到来，不会离开</span></span><br><span class="line"><span class="string">        异步：提交完任务便执行下一步代码，不会原地等待数据结果的到来</span></span><br><span class="line"><span class="string">        &quot;&quot;&quot;</span></span><br><span class="line">        res = pool.submit(task, i).add_done_callback(callback)</span><br><span class="line">        </span><br><span class="line">        </span><br><span class="line">  </span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">其实这就是异步回调机制，总结下，其实只需要三步</span></span><br><span class="line"><span class="string">	from concurrent.futures import ProcessPoolExecutor</span></span><br><span class="line"><span class="string">	pool = ProcessPoolExecutor(5) </span></span><br><span class="line"><span class="string">	 res = pool.submit(task, i).add_done_callback(callback)</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="三十三、协程基本原理"><a href="#三十三、协程基本原理" class="headerlink" title="三十三、协程基本原理"></a>三十三、协程基本原理</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">进程：资源单位</span></span><br><span class="line"><span class="string">线程：执行单位</span></span><br><span class="line"><span class="string">协程：其实这个就是程序员意淫出来的一个 根本不存在</span></span><br><span class="line"><span class="string">	单线程下实现并发</span></span><br><span class="line"><span class="string">	我们程序员自己去写代码检测我们的程序所有IO</span></span><br><span class="line"><span class="string">	然后遇到IO，我们在代码级别上实现切换</span></span><br><span class="line"><span class="string">	这样就会给cpu带来错觉，并没有IO</span></span><br><span class="line"><span class="string">	从而提升代码的运行效率</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">多道技术</span></span><br><span class="line"><span class="string">	切换+保存状态</span></span><br><span class="line"><span class="string">	cpu两种切换	</span></span><br><span class="line"><span class="string">		1.程序遇到IP</span></span><br><span class="line"><span class="string">		2.程序长时间占用</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>

<h2 id="三十四、genvet模块"><a href="#三十四、genvet模块" class="headerlink" title="三十四、genvet模块"></a>三十四、genvet模块</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"></span><br></pre></td></tr></table></figure>


            </div>

            <!-- Post Comments -->
            
    <!-- 使用 DISQUS_CLICK -->
<div id="disqus-comment">
    <div id="disqus_thread"></div>

<!-- add animation -->
<style>
	.disqus_click_btn {
            line-height: 30px;
            margin: 0;
            min-width: 50px;
            padding: 0 14px;
            display: inline-block;
            font-family: "Roboto", "Helvetica", "Arial", sans-serif;
            font-size: 14px;
            font-weight: 400;
            text-transform: uppercase;
            letter-spacing: 0;
            overflow: hidden;
            will-change: box-shadow;
            transition: box-shadow .2s cubic-bezier(.4, 0, 1, 1), background-color .2s cubic-bezier(.4, 0, .2, 1), color .2s cubic-bezier(.4, 0, .2, 1);
            outline: 0;
            cursor: pointer;
            text-decoration: none;
            text-align: center;
            vertical-align: middle;
            border: 0;
            background: rgba(158, 158, 158, .2);
            box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
            color: #fff;
            background-color: #7EC0EE;
            text-shadow: 0
        }
</style>
	
<div class="btn_click_load" id="disqus_bt"> 
    <button class="disqus_click_btn">点击查看评论</button>
</div>

<!--
<script type="text/javascript">
$('.btn_click_load').click(function() {
    /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
    var disqus_shortname = 'http-miccall-tech'; // required: replace example with your forum shortname

    /* * * DON'T EDIT BELOW THIS LINE * * */
    (function() {
      var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
      dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
      (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();

    document.getElementById('disqus_bt').style.display = "none";
});
</script>
-->
<script type="text/javascript">
    var disqus_config = function () {
        this.page.url = 'https://gitee.com/AmeX/amelin-ting.git/2017/04/01/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/';  // Replace PAGE_URL with your page's canonical URL variable
        this.page.identifier = 'https://gitee.com/AmeX/amelin-ting.git/2017/04/01/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/'; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
    };
</script>

<script type="text/javascript">
    $('.btn_click_load').click(function() {  //click to load comments
        (function() { // DON'T EDIT BELOW THIS LINE
            var d = document;
            var s = d.createElement('script');
            s.src = '//http-miccall-tech.disqus.com/embed.js';
            s.setAttribute('data-timestamp', + new Date());
            (d.head || d.body).appendChild(s);
        })();
        $('.btn_click_load').css('display','none');
    });
</script>
</div>
<style>
    #disqus-comment{
        background-color: #eee;
        padding: 2pc;
    }
</style>


        </div>
        <!-- Copyright 版权 start -->
                <div id="copyright">
            <ul>
                <li>&copy;Powered By <a target="_blank" rel="noopener" href="https://hexo.io/zh-cn/" style="border-bottom: none;">hexo</a></li>
                <li>Design: <a target="_blank" rel="noopener" href="http://miccall.tech " style="border-bottom: none;">miccall</a></li>
            </ul>
            
                <span id="busuanzi_container_site_pv">本站总访问量<span id="busuanzi_value_site_pv"></span>次</span>
			
        </div>
    </div>
</body>



 	
</html>
